﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace PIM_ATE.rflight
{
    class ClsRfPIMforDesktop : JcPIMRunner
    {
        const string lf = "";
        //初始化状态
        bool m_isInited;
        //设备列表(NAME, IP)
        Dictionary<string, JcPIMInstrumentInfo> m_devices;
        //连接实例
        ClsRfPimCmd m_compatObj;
        //当前设置
        JcPIMDataSettings m_pim_settings;
        //结果列表
        List<JcPIMDataResults> m_pim_resultLists = new List<JcPIMDataResults>();
        //控制实例
        ImpCtrl m_ctrl;
        //异步句柄
        delegate bool DelStartTest();

        public ClsRfPIMforDesktop(Dictionary<string, JcPIMInstrumentInfo> devices)
        {
            m_devices = devices;
            m_compatObj = new ClsRfPimCmd(GDefine.IS_COMPAT_DEBUG_TEST);
            m_isInited = false;
            m_ctrl = new ImpCtrl();
        }
        public override void start_settings(JcPIMDataSettings settings)
        {
            m_pim_settings = settings;
            m_pim_resultLists.Clear();
            if (settings.isRandom || GDefine.IS_COMPAT_DEBUG_TEST)
            {
                m_compatObj.SetDebug(true);
                m_compatObj.SetDebugMaxMin(settings.RandomMax, settings.RandomMin);
            }
            else
            {
                m_compatObj.SetDebug(false);
            }
        }
        public override void start_test()
        {
            DelStartTest del_start_test = new DelStartTest(start_test_sync);
            del_start_test.BeginInvoke(evt_complete_test_async, del_start_test);
        }
        public override void stop_test()
        {
            Monitor.Enter(m_ctrl);
            m_ctrl.bQuit = true;
            Monitor.Exit(m_ctrl);
        }
        bool start_test_sync()
        {
            bool complete = false;
            if (init(m_devices[m_pim_settings.Band_Name].instrAddress))
            {
                if (m_pim_settings.Mode == ImMode.Freq)
                    complete = freq_sweep();
                else
                    complete = time_sweep();
            }
            return complete;
        }
        void evt_show_msg(string msg, MSG_TYPE type)
        {
            //if (type != MSG_TYPE.LOG_NET)
            On_evt_show_log_handle(msg, null);

            if (type == MSG_TYPE.ERROR_NET || type == MSG_TYPE.ERROR_SET || type == MSG_TYPE.ERROR_TEST)
            {
                On_evt_show_error_handle(msg, null);
                //evt_complete_test(null, null);
            }
        }
        void evt_update_ui(object obj, EventArgs e)
        {//完成点事件
            On_evt_get_point_handle(obj, e);
        }
        void evt_complete_test_async(IAsyncResult result)
        {//完成测试事件(异步)
            bool complete = (result.AsyncState as DelStartTest).EndInvoke(result);

            if (m_isInited) m_compatObj.Close();
            m_isInited = false;
            evt_show_msg("connect: closen" + lf, MSG_TYPE.LOG_NET);

            if (complete)
                On_evt_complete_test_handle(m_pim_resultLists, null);
            else
                On_evt_complete_test_handle(null, null);
        }
        bool init(string address)
        {//初始化
            if (m_compatObj.Connect(address, 5044))
            {//连接
                evt_show_msg("connect: success" + lf, MSG_TYPE.LOG_NET);
                m_isInited = true;
            }
            else
            {
                m_isInited = false;
                evt_show_msg("connect-Error: " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
            }

            return m_isInited;
        }

        bool freq_sweep()
        {//扫频
            Monitor.Enter(m_ctrl);
            m_ctrl.bQuit = false;
            Monitor.Exit(m_ctrl);

            double freq_mhz = 0;
            double val = 0;
            double p1 = 0, p2 = 0;
            int sweeptype = 0;


            if (!m_compatObj.Reset())
            {
                evt_show_msg("exec-Error(Reset): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.setFreqBand(0))
            {//1.选择第一个系统频段："SYST:FREQ:BAND 0\n"
                evt_show_msg("exec-Error(setFreqBand): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            /*机械开关稳定时间至少300ms*/
            if (!m_compatObj.setMeasMode(false))
            {//2.设置系统测量模式为反射："SYST:MEAS:MODE REFL\n"
                evt_show_msg("exec-Error(setMeasMode): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            Thread.Sleep(500);
            /*机械开关稳定时间至少300ms*/
            if (!m_compatObj.setIMFreqRang(m_pim_settings.RXs, m_pim_settings.RXe))
            {//RXL-RXH
                evt_show_msg("exec-Error(setIMFreqRang): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.setPimOrd((int)m_pim_settings.Order))
            {//5.设置系统互调阶数位3："SYST:PIM:ORD 3\n"
                evt_show_msg("exec-Error(setPimOrd): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.setCarrFreq(m_pim_settings.F1Set, m_pim_settings.F2Set))
            {//4.设置载波1频率为1805.0 MHz，载波2频率为1880.0 MHz："CARR:FREQ 1805.0,1880.0\n"
                evt_show_msg("exec-Error(setCarrFreq): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.SetCarrierAtt(1, 15))
            {//衰减器1
                evt_show_msg("exec-Error(setCarrPow): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.SetCarrierAtt(2, 15))
            {
                evt_show_msg("exec-Error(setCarrPow): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.setInitImm())
            {//9.设置立即启动测试："INIT:IMM\n"
                evt_show_msg("exec-Error(setInitImm): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }


            List<XPlot> lstPoint = new List<XPlot>();
            //扫频状态
            List<int> SweepType = new List<int>();
            List<int> IsUpSweep = new List<int>();
            List<int> IsDownSweep = new List<int>();
            double n1 = 0, n2 = 0, f = 0, g = 0;
            if (m_pim_settings.StepRx == 0)
            {//TX步进
                if (m_pim_settings.Step1 <= 0) m_pim_settings.Step1 = 1;
                n1 = Math.Ceiling((m_pim_settings.F1e - m_pim_settings.F1s) / m_pim_settings.Step1) + 1;
                if (m_pim_settings.Step2 <= 0) m_pim_settings.Step2 = 1;
                n2 = Math.Ceiling((m_pim_settings.F2e - m_pim_settings.F2s) / m_pim_settings.Step2) + 1;

                f = m_pim_settings.F1s;
                for (int i = 0; i < n1; ++i)
                {//上扫频
                    if (f > m_pim_settings.F1e) f = m_pim_settings.F1e;
                    double fpim = sumPIMFreq(f, m_pim_settings.F2e, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                    lstPoint.Add(new XPlot(f, m_pim_settings.F2e, fpim));
                    f += m_pim_settings.Step1;
                    if (IsUpSweep.Count == 0)
                    {
                        IsUpSweep.Add(0);
                    }
                    else
                    {
                        IsUpSweep.Add(1);
                    }

                }

                f = m_pim_settings.F2e;
                for (int i = 0; i < n2; ++i)
                {//下扫频
                    if (f < m_pim_settings.F2s) f = m_pim_settings.F2s;
                    double fpim = sumPIMFreq(m_pim_settings.F1s, f, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                    lstPoint.Add(new XPlot(m_pim_settings.F1s, f, fpim));
                    f -= m_pim_settings.Step2;
                    if (IsDownSweep.Count == 0)
                    {
                        IsDownSweep.Add(0);
                    }
                    else
                    {
                        IsDownSweep.Add(2);
                    }
                }
            }
            else
            {//rx步进
                double n = Math.Ceiling((m_pim_settings.RXe - m_pim_settings.RXs) / m_pim_settings.StepRx) + 1;
                f = m_pim_settings.RXs;
                for (int i = 0; i < n; ++i, f += m_pim_settings.StepRx)
                {
                    if (f > m_pim_settings.RXe) f = m_pim_settings.RXe;

                    double f1 = sumF1FromPIMFreq(m_pim_settings.F2Set, f, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                    if (f1 >= m_pim_settings.F1Set && f1 <= m_pim_settings.F2Set)
                    {
                        g = sumPIMFreq(f1, m_pim_settings.F2Set, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                        lstPoint.Add(new XPlot(f1, m_pim_settings.F2Set, g));
                        n1++;
                        if (IsUpSweep.Count == 0)
                        {
                            IsUpSweep.Add(0);
                        }
                        else
                        {
                            IsUpSweep.Add(1);
                        }
                    }

                    f1 = sumF2FromPIMFreq(m_pim_settings.F2Set, f, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                    if (f1 >= m_pim_settings.F1Set && f1 <= m_pim_settings.F2Set)
                    {
                        g = sumPIMFreq(f1, m_pim_settings.F2Set, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                        lstPoint.Add(new XPlot(f1, m_pim_settings.F2Set, g));
                        n1++;
                        if (IsUpSweep.Count == 0)
                        {
                            IsUpSweep.Add(0);
                        }
                        else
                        {
                            IsUpSweep.Add(1);
                        }
                    }
                }

                f = m_pim_settings.RXs;
                for (int i = 0; i < n; ++i, f += m_pim_settings.StepRx)
                {
                    if (f > m_pim_settings.RXe) f = m_pim_settings.RXe;
                    double f2 = sumF2FromPIMFreq(m_pim_settings.F1Set, f, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                    if (f2 >= m_pim_settings.F1Set && f2 <= m_pim_settings.F2Set)
                    {
                        g = sumPIMFreq(m_pim_settings.F1Set, f2, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                        lstPoint.Add(new XPlot(m_pim_settings.F1Set, f2, g));
                        n2++;
                        if (IsDownSweep.Count == 0)
                        {
                            IsDownSweep.Add(0);
                        }
                        else
                        {
                            IsDownSweep.Add(2);
                        }
                    }

                    f2 = sumF1FromPIMFreq(m_pim_settings.F1Set, f, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                    if (f2 >= m_pim_settings.F1Set && f2 <= m_pim_settings.F2Set)
                    {
                        g = sumPIMFreq(m_pim_settings.F1Set, f2, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                        lstPoint.Add(new XPlot(m_pim_settings.F1Set, f2, g));
                        n2++;
                        if (IsDownSweep.Count == 0)
                        {
                            IsDownSweep.Add(0);
                        }
                        else
                        {
                            IsDownSweep.Add(2);
                        }
                    }
                }
            }

            DateTime time = DateTime.Now;
            for (int j = 0; j < IsDownSweep.Count; j++)
            {
                IsUpSweep.Add(IsDownSweep[j]);
            }
            SweepType = IsUpSweep;
            int sweep = 0;
            #region 原循环测试
            bool result = true;
            for (int i = 0; i < lstPoint.Count; ++i)
            {//循环测试            
                Monitor.Enter(m_ctrl);
                bool isQuit = m_ctrl.bQuit;
                Monitor.Exit(m_ctrl);
                if (isQuit)
                {//手动结束
                    m_compatObj.setInitImm(false);
                    evt_show_msg("exec: test stop" + lf, MSG_TYPE.LOG_TEST);
                    return true;
                }
                freq_mhz = lstPoint[i].RX;
                //if (!m_compatObj.setIMFreqRang(freq_mhz, freq_mhz))
                //{//RXL-RXH
                //    evt_show_msg("exec-Error(setIMFreqRang): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                //    return false;
                //}

                if (!m_compatObj.setCarrFreq(lstPoint[i].X1, lstPoint[i].X2, "mhz"))
                {//4.设置载波1频率为1805.0 MHz，载波2频率为1880.0 MHz："CARR:FREQ 1805.0,1880.0\n"
                    evt_show_msg("exec-Error(setCarrFreq): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }
                //double freq = 0d;
                //m_compatObj.getIMFreq(ref freq);
                //if (freq_mhz != freq)
                //{
                //    evt_show_msg("exec-Error(计算频点freq不一致): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                //    result = false;
                //    break;
                //}
                m_compatObj.SetTxPower(m_pim_settings.TX1 + m_pim_settings.Offset1, m_pim_settings.TX2 + m_pim_settings.Offset2);

                double minp = 0, maxp = 0d;
                m_compatObj.GetCarrierPowerRange(ref minp, ref maxp);
                if ((m_pim_settings.TX1 + m_pim_settings.Offset1) > maxp || (m_pim_settings.TX1 + m_pim_settings.Offset1) < minp)
                {
                    evt_show_msg(string.Format("exec-Error(功率P1设定超出范围):P1={0},Min={1},Max={2}", m_pim_settings.TX1 + m_pim_settings.Offset1, minp, maxp) + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }
                if ((m_pim_settings.TX2 + m_pim_settings.Offset2) > maxp || (m_pim_settings.TX2 + m_pim_settings.Offset2) < minp)
                {
                    evt_show_msg(string.Format("exec-Error(功率P2设定超出范围):P2={0},Min={1},Max={2}", m_pim_settings.TX2 + m_pim_settings.Offset2, minp, maxp) + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }

                if (!m_compatObj.Carrier1Leveling(m_pim_settings.TX1 + m_pim_settings.Offset1))
                {//调载波功率1
                    evt_show_msg("exec-Error(Carrier1Leveling): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }
                if (!m_compatObj.getCarrPow(1, ref p1, ref p2))
                {//获取功率1
                    result = false;
                    break;
                }
                if (!m_compatObj.Carrier2Leveling(m_pim_settings.TX2 + m_pim_settings.Offset2))
                {
                    evt_show_msg("exec-Error(Carrier2Leveling): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }
                if (!m_compatObj.getCarrPow(2, ref p1, ref p2))
                {//获取功率2
                    result = false;
                    break;
                }
                Thread.Sleep(50);



                if (!m_compatObj.getFixPimData(freq_mhz, ref val))
                {//11.查询点频互调数据："FIX:PIM:DATA?\n"
                    m_compatObj.setInitImm(false);
                    evt_show_msg("exec-Error(getFixPimData): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }


                evt_show_msg("exec: Set f1 = " + lstPoint[i].X1.ToString() + " ,f2 = " +
                                                 lstPoint[i].X2.ToString() + lf, MSG_TYPE.LOG_TEST);
                val += m_pim_settings.Offset_RX;

                JcPIMDataResults entry = new JcPIMDataResults();
                entry.No = i + 1;
                entry.F1 = (float)lstPoint[i].X1;
                entry.F2 = (float)lstPoint[i].X2;
                entry.Im_F = (float)freq_mhz;
                entry.Im_V = (float)val;
                entry.P1 = (float)Math.Round(p1, 1);
                entry.P2 = (float)Math.Round(p2, 1);
                entry.n1 = (int)n1;
                entry.n2 = (int)n2;
                if (m_pim_settings.isRandom)
                {
                    entry.Time_now = time;
                    time = time.AddSeconds(0.5);
                }
                else
                {
                    entry.Time_now = DateTime.Now;
                }

                m_pim_resultLists.Add(entry);
                evt_update_ui(entry, null);
            }
            #endregion
            m_compatObj.setInitImm(false);
            return result;
        }

        bool time_sweep()
        {//点频
            Monitor.Enter(m_ctrl);
            m_ctrl.bQuit = false;
            Monitor.Exit(m_ctrl);

            double freq_mhz = 0;
            double val = 0;
            double p1 = 0, p2 = 0;

            if (!m_compatObj.Reset())
            {
                evt_show_msg("exec-Error(Reset): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.setFreqBand(0))
            {//1.选择第一个系统频段："SYST:FREQ:BAND 0\n"
                evt_show_msg("exec-Error(setFreqBand): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            /*机械开关稳定时间至少300ms*/
            if (!m_compatObj.setMeasMode(false))
            {//2.设置系统测量模式为反射："SYST:MEAS:MODE REFL\n"
                evt_show_msg("exec-Error(setMeasMode): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            Thread.Sleep(500);
            /*机械开关稳定时间至少300ms*/
            if (!m_compatObj.setIMFreqRang(m_pim_settings.RXs, m_pim_settings.RXs))
            {//RXL-RXH
                evt_show_msg("exec-Error(setIMFreqRang): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.setPimOrd((int)m_pim_settings.Order))
            {//5.设置系统互调阶数位3："SYST:PIM:ORD 3\n"
                evt_show_msg("exec-Error(setPimOrd): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.setCarrFreq(m_pim_settings.F1s, m_pim_settings.F2e, "mhz"))
            {//4.设置载波1频率为1805.0 MHz，载波2频率为1880.0 MHz："CARR:FREQ 1805.0,1880.0\n"
                evt_show_msg("exec-Error(setCarrFreq): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.SetCarrierAtt(1, 15))
            {//衰减器1
                evt_show_msg("exec-Error(setCarrPow): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.SetCarrierAtt(2, 15))
            {
                evt_show_msg("exec-Error(setCarrPow): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.setInitImm())
            {
                evt_show_msg("exec-Error(setInitImm): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }

            int i = 0;
            long time_start = DateTime.Now.Ticks;
            DateTime time = DateTime.Now;
            bool result = true;
            while (true)
            {
                Monitor.Enter(m_ctrl);
                bool isQuit = m_ctrl.bQuit;
                Monitor.Exit(m_ctrl);
                if (isQuit)
                {//手动结束测试
                    m_compatObj.setInitImm(false);
                    evt_show_msg("exec: test stop" + lf, MSG_TYPE.LOG_TEST);
                    return true;
                }

                TimeSpan elapsedSpan = new TimeSpan(DateTime.Now.Ticks - time_start);
                if (elapsedSpan.TotalSeconds >= m_pim_settings.Time)
                {
                    break;
                }
                m_compatObj.SetTxPower(m_pim_settings.TX1 + m_pim_settings.Offset1, m_pim_settings.TX2 + m_pim_settings.Offset2);
                double minp = 0, maxp = 0d;
                m_compatObj.GetCarrierPowerRange(ref minp, ref maxp);
                if ((m_pim_settings.TX1 + m_pim_settings.Offset1) > maxp || (m_pim_settings.TX1 + m_pim_settings.Offset1) < minp)
                {
                    evt_show_msg(string.Format("exec-Error(功率P1设定超出范围):P1={0},Min={1},Max={2}", m_pim_settings.TX1 + m_pim_settings.Offset1, minp, maxp) + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }
                if ((m_pim_settings.TX2 + m_pim_settings.Offset2) > maxp || (m_pim_settings.TX2 + m_pim_settings.Offset2) < minp)
                {
                    evt_show_msg(string.Format("exec-Error(功率P2设定超出范围):P2={0},Min={1},Max={2}", m_pim_settings.TX2 + m_pim_settings.Offset2, minp, maxp) + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }

                if (!m_compatObj.Carrier1Leveling(m_pim_settings.TX1 + m_pim_settings.Offset1))
                {//调载波功率1
                    evt_show_msg("exec-Error(Carrier1Leveling): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }
                if (!m_compatObj.getCarrPow(1, ref p1, ref p2))
                {//获取功率1
                    //  p1 = m_pim_settings.TX1 + m_pim_settings.Offset1;
                    result = false;
                    break;
                }

                if (!m_compatObj.Carrier2Leveling(m_pim_settings.TX2 + m_pim_settings.Offset2))
                {
                    evt_show_msg("exec-Error(Carrier2Leveling): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }
                if (!m_compatObj.getCarrPow(2, ref p1, ref p2))
                {//获取功率2
                    // p2 = m_pim_settings.TX1 + m_pim_settings.Offset1;
                    result = false;
                    break;
                }

                Thread.Sleep(50);



                freq_mhz = m_pim_settings.RXs;
                if (!m_compatObj.getFixPimData(freq_mhz, ref val))
                {//11.查询点频互调数据："FIX:PIM:DATA?\n"
                    m_compatObj.setInitImm(false);
                    evt_show_msg("exec-Error(getFixPimData): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }
                val += m_pim_settings.Offset_RX;

                JcPIMDataResults entry = new JcPIMDataResults();
                entry.No = i;
                entry.F1 = (float)m_pim_settings.F1s;
                entry.F2 = (float)m_pim_settings.F2e;
                entry.Im_F = (float)freq_mhz;
                entry.Im_V = (float)val;
                entry.P1 = (float)p1;
                entry.P2 = (float)p2;
                entry.n1 = 0;
                entry.n2 = 0;
                if (m_pim_settings.isRandom)
                {
                    entry.Time_now = time;
                    time = time.AddSeconds(0.5);
                }
                else
                {
                    entry.Time_now = DateTime.Now;
                }
                m_pim_resultLists.Add(entry);
                evt_update_ui(entry, null);
                i++;
            }
            m_compatObj.setInitImm(false);
            return result;
        }


    }

    class ClsRfPIMforDesktopCom : JcPIMRunner
    {
        const string lf = "";
        //初始化状态
        bool m_isInited;
        //设备列表(NAME, IP)
        Dictionary<string, JcPIMInstrumentInfo> m_devices;
        //连接实例
        ClsRfPimCmdCom m_compatObj;
        //当前设置
        JcPIMDataSettings m_pim_settings;
        //结果列表
        List<JcPIMDataResults> m_pim_resultLists = new List<JcPIMDataResults>();
        //控制实例
        ImpCtrl m_ctrl;
        //异步句柄
        delegate bool DelStartTest();

        public ClsRfPIMforDesktopCom(Dictionary<string, JcPIMInstrumentInfo> devices)
        {
            m_devices = devices;
            m_compatObj = new ClsRfPimCmdCom(GDefine.IS_COMPAT_DEBUG_TEST);
            m_isInited = false;
            m_ctrl = new ImpCtrl();
        }
        public override void start_settings(JcPIMDataSettings settings)
        {
            m_pim_settings = settings;
            m_pim_resultLists.Clear();
            if (settings.isRandom || GDefine.IS_COMPAT_DEBUG_TEST)
            {
                m_compatObj.SetDebug(true);
                m_compatObj.SetDebugMaxMin(settings.RandomMax, settings.RandomMin);
            }
            else
            {
                m_compatObj.SetDebug(false);
            }
        }
        public override void start_test()
        {
            DelStartTest del_start_test = new DelStartTest(start_test_sync);
            del_start_test.BeginInvoke(evt_complete_test_async, del_start_test);
        }
        public override void stop_test()
        {
            Monitor.Enter(m_ctrl);
            m_ctrl.bQuit = true;
            Monitor.Exit(m_ctrl);
        }
        bool start_test_sync()
        {
            bool complete = false;
            if (init(m_devices[m_pim_settings.Band_Name].instrAddress))
            {
                if (m_pim_settings.Mode == ImMode.Freq)
                    complete = freq_sweep();
                else
                    complete = time_sweep();
            }
            return complete;
        }
        void evt_show_msg(string msg, MSG_TYPE type)
        {
            //if (type != MSG_TYPE.LOG_NET)
            On_evt_show_log_handle(msg, null);

            if (type == MSG_TYPE.ERROR_NET || type == MSG_TYPE.ERROR_SET || type == MSG_TYPE.ERROR_TEST)
            {
                On_evt_show_error_handle(msg, null);
                //evt_complete_test(null, null);
            }
        }
        void evt_update_ui(object obj, EventArgs e)
        {
            On_evt_get_point_handle(obj, e);
        }
        void evt_complete_test_async(IAsyncResult result)
        {
            bool complete = (result.AsyncState as DelStartTest).EndInvoke(result);

            if (m_isInited) m_compatObj.Close();
            m_isInited = false;
            evt_show_msg("connect: closen" + lf, MSG_TYPE.LOG_NET);

            if (complete)
                On_evt_complete_test_handle(m_pim_resultLists, null);
            else
                On_evt_complete_test_handle(null, null);
        }
        bool init(string address)
        {
            if (m_compatObj.Connect(address))
            {
                evt_show_msg("connect: success" + lf, MSG_TYPE.LOG_NET);
                m_isInited = true;
            }
            else
            {
                m_compatObj.Close();
                m_isInited = false;
                evt_show_msg("connect-Error: " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
            }
            return m_isInited;
        }

        bool freq_sweep()
        {
            Monitor.Enter(m_ctrl);
            m_ctrl.bQuit = false;
            Monitor.Exit(m_ctrl);

            double freq_mhz = 0;
            double val = 0;
            double p1 = 0, p2 = 0;        


            if (!m_compatObj.Reset())
            {
                evt_show_msg("exec-Error(Reset): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }

            if (!m_compatObj.setFreqBand(0))
            {
                evt_show_msg("exec-Error(setFreqBand): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }            
            
            if (!m_compatObj.setSystMode(m_pim_settings.Port_TX1.ToString()))
            {
                evt_show_msg("exec-Error(setSystMode): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            
            if (!m_compatObj.setImOrd((int)m_pim_settings.Order))
            {
                evt_show_msg("exec-Error(setImOrd): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.setCarrFreq(m_pim_settings.F1s, m_pim_settings.F2e))
            {
                evt_show_msg("exec-Error(setCarrFreq): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.SetCarrierAtt(1, 15))
            {//衰减器1 
                evt_show_msg("exec-Error(SetCarrierAtt): 1 " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.SetCarrierAtt(2, 15))
            {
                evt_show_msg("exec-Error(SetCarrierAtt): 2 " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.setCarrOutp())
            {
                evt_show_msg("exec-Error(setCarrOutp): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }

            #region
            List<XPlot> lstPoint = new List<XPlot>();
            double n1 = 0, n2 = 0, f = 0;
            if (m_pim_settings.StepRx == 0)
            {
                if (m_pim_settings.Step1 <= 0) m_pim_settings.Step1 = 5;
                n1 = Math.Ceiling((m_pim_settings.F1e - m_pim_settings.F1s) / m_pim_settings.Step1) + 1;
                if (m_pim_settings.Step2 <= 0) m_pim_settings.Step2 = 5;
                n2 = Math.Ceiling((m_pim_settings.F2e - m_pim_settings.F2s) / m_pim_settings.Step2) + 1;

                f = m_pim_settings.F1s;
                for (int i = 0; i < n1; ++i)
                {
                    if (f > m_pim_settings.F1e) f = m_pim_settings.F1e;
                    double fpim = sumPIMFreq(f, m_pim_settings.F2e, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                    lstPoint.Add(new XPlot(f, m_pim_settings.F2e, fpim));
                    f += m_pim_settings.Step1;
                }

                f = m_pim_settings.F2e;
                for (int i = 0; i < n2; ++i)
                {
                    if (f < m_pim_settings.F2s) f = m_pim_settings.F2s;
                    double fpim = sumPIMFreq(m_pim_settings.F1s, f, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                    lstPoint.Add(new XPlot(m_pim_settings.F1s, f, fpim));
                    f -= m_pim_settings.Step2;
                }
            }
            else
            {
                double n = Math.Ceiling((m_pim_settings.RXe - m_pim_settings.RXs) / m_pim_settings.StepRx) + 1;
                f = m_pim_settings.RXs;
                for (int i = 0; i < n; ++i)
                {
                    if (f > m_pim_settings.RXe) f = m_pim_settings.RXe;
                    double f1 = sumF1FromPIMFreq(m_pim_settings.F2Set, f, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                    f += m_pim_settings.StepRx;

                    if (f1 < m_pim_settings.F1Set || f1 > m_pim_settings.F2Set) continue;
                    lstPoint.Add(new XPlot(f1, m_pim_settings.F2Set, 0));
                    n1++;
                }

                f = m_pim_settings.RXs;
                for (int i = 0; i < n; ++i)
                {
                    if (f > m_pim_settings.RXe) f = m_pim_settings.RXe;
                    double f2 = sumF2FromPIMFreq(m_pim_settings.F1Set, f, (int)m_pim_settings.Order, m_pim_settings.isHigh);
                    f += m_pim_settings.StepRx;

                    if (f2 < m_pim_settings.F1Set || f2 > m_pim_settings.F2Set) continue;
                    lstPoint.Add(new XPlot(m_pim_settings.F1Set, f2, 0));
                    n2++;
                }
            }
            #endregion

            #region
            bool result = true;
            for (int i = 0; i < lstPoint.Count; ++i)
            {          
                Monitor.Enter(m_ctrl);
                bool isQuit = m_ctrl.bQuit;
                Monitor.Exit(m_ctrl);
                if (isQuit)
                {
                    m_compatObj.setCarrOutp(false);
                    evt_show_msg("exec: test stop" + lf, MSG_TYPE.LOG_TEST);
                    return true;
                }               

                if (!m_compatObj.setCarrFreq(lstPoint[i].X1, lstPoint[i].X2, "mhz"))
                {
                    evt_show_msg("exec-Error(setCarrFreq): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }

                m_compatObj.SetTxPower(m_pim_settings.TX1 + m_pim_settings.Offset1, m_pim_settings.TX2 + m_pim_settings.Offset2);

                if (!m_compatObj.Carrier1Leveling(m_pim_settings.TX1 + m_pim_settings.Offset1))
                {//调载波功率1
                    evt_show_msg("exec-Error(Carrier1Leveling): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }
                if (!m_compatObj.getCarrPow(1, ref p1, ref p2))
                {//获取功率1
                    evt_show_msg("exec-Error(getCarrPow): 1" + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }
                if (!m_compatObj.Carrier2Leveling(m_pim_settings.TX2 + m_pim_settings.Offset2))
                {
                    evt_show_msg("exec-Error(Carrier2Leveling): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }
                if (!m_compatObj.getCarrPow(2, ref p1, ref p2))
                {
                    evt_show_msg("exec-Error(getCarrPow): 2" + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }
                Thread.Sleep(50);

                if (!m_compatObj.getImPow(ref val))
                {
                    m_compatObj.setCarrOutp(false);
                    evt_show_msg("exec-Error(getImPow): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }

                evt_show_msg("exec: Set f1 = " + lstPoint[i].X1.ToString() + " ,f2 = " +
                                                 lstPoint[i].X2.ToString() + lf, MSG_TYPE.LOG_TEST);
                freq_mhz = lstPoint[i].RX;
                val += m_pim_settings.Offset_RX;
                JcPIMDataResults entry = new JcPIMDataResults();
                entry.No = i + 1;
                entry.F1 = (float)lstPoint[i].X1;
                entry.F2 = (float)lstPoint[i].X2;
                entry.Im_F = (float)freq_mhz;
                entry.Im_V = (float)val;
                entry.P1 = (float)Math.Round(p1, 1);
                entry.P2 = (float)Math.Round(p2, 1);
                entry.n1 = (int)n1;
                entry.n2 = (int)n2;
                entry.Time_now = DateTime.Now;

                m_pim_resultLists.Add(entry);
                evt_update_ui(entry, null);
            }
            #endregion
            m_compatObj.setCarrOutp(false);
            return result;
        }

        bool time_sweep()
        {//点频

            Monitor.Enter(m_ctrl);
            m_ctrl.bQuit = false;
            Monitor.Exit(m_ctrl);

            double freq_mhz = 0;
            double val = 0;
            double p1 = 0, p2 = 0;

            if (!m_compatObj.Reset())
            {
                evt_show_msg("exec-Error(Reset): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }

            if (!m_compatObj.setFreqBand(0))
            {
                evt_show_msg("exec-Error(setFreqBand): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }

            if (!m_compatObj.setSystMode(m_pim_settings.Port_TX1.ToString()))
            {
                evt_show_msg("exec-Error(setSystMode): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }

            if (!m_compatObj.setImOrd((int)m_pim_settings.Order))
            {
                evt_show_msg("exec-Error(setImOrd): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.setCarrFreq(m_pim_settings.F1s, m_pim_settings.F2e))
            {
                evt_show_msg("exec-Error(setCarrFreq): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.SetCarrierAtt(1, 15))
            {
                evt_show_msg("exec-Error(SetCarrierAtt): 1 " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.SetCarrierAtt(2, 15))
            {
                evt_show_msg("exec-Error(SetCarrierAtt): 2 " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }
            if (!m_compatObj.setCarrOutp())
            {
                evt_show_msg("exec-Error(setCarrOutp): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                return false;
            }

            int i = 0;
            long time_start = DateTime.Now.Ticks;          
            bool result = true;
            if (m_pim_settings.Time == 0)
                m_pim_settings.Time = 10;
            while (true)
            {
                Monitor.Enter(m_ctrl);
                bool isQuit = m_ctrl.bQuit;
                Monitor.Exit(m_ctrl);
                if (isQuit)
                {//手动结束测试
                    m_compatObj.setCarrOutp(false);
                    evt_show_msg("exec: test stop" + lf, MSG_TYPE.LOG_TEST);
                    return true;
                }

                TimeSpan elapsedSpan = new TimeSpan(DateTime.Now.Ticks - time_start);
                if (elapsedSpan.TotalSeconds >= m_pim_settings.Time)
                {
                    break;
                }
                m_compatObj.SetTxPower(m_pim_settings.TX1 + m_pim_settings.Offset1, m_pim_settings.TX2 + m_pim_settings.Offset2);               

                if (!m_compatObj.Carrier1Leveling(m_pim_settings.TX1 + m_pim_settings.Offset1))
                {//调载波功率1
                    evt_show_msg("exec-Error(Carrier1Leveling): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }
                if (!m_compatObj.getCarrPow(1, ref p1, ref p2))
                {//获取功率1
                    evt_show_msg("exec-Error(getCarrPow): 1" + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }

                if (!m_compatObj.Carrier2Leveling(m_pim_settings.TX2 + m_pim_settings.Offset2))
                {
                    evt_show_msg("exec-Error(Carrier2Leveling): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }
                if (!m_compatObj.getCarrPow(2, ref p1, ref p2))
                {//获取功率2
                    evt_show_msg("exec-Error(getCarrPow): 2" + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }

                Thread.Sleep(50);

                
                if (!m_compatObj.getImPow(ref val))
                {
                    m_compatObj.setCarrOutp(false);
                    evt_show_msg("exec-Error(getImPow): " + m_compatObj.fnGetError() + lf, MSG_TYPE.ERROR_NET);
                    result = false;
                    break;
                }
                freq_mhz = m_pim_settings.RXs;
                val += m_pim_settings.Offset_RX;
                JcPIMDataResults entry = new JcPIMDataResults();
                entry.No = i;
                entry.F1 = (float)m_pim_settings.F1s;
                entry.F2 = (float)m_pim_settings.F2e;
                entry.Im_F = (float)freq_mhz;
                entry.Im_V = (float)val;
                entry.P1 = (float)p1;
                entry.P2 = (float)p2;
                entry.n1 = 0;
                entry.n2 = 0;              
                    entry.Time_now = DateTime.Now;
                m_pim_resultLists.Add(entry);
                evt_update_ui(entry, null);
                i++;
            }
            m_compatObj.setCarrOutp(false);
            return result;
        }


    }
}
